#include "TM1668.h"
#include <intrins.h>       /* 声明void _nop_(void); */


#if	0
static void Delay_SEG(unsigned char n)
{
	unsigned char i = 0;
	for (i = 0; i < n; i++)
	{
		// _nop_();	
	}
}
#else
#define		Delay_SEG(x)		_nop_();
#endif
/*
    开始传输数据
*/
void TM1668_Start(void)
{
	GPIO_CLK  = 1;
	GPIO_DIO  = 1;
	GPIO_STB  = 0;
	Delay_SEG(1);
}

void TM1668_Sleep_IO(void){
	GPIO_CLK  = 0;
	GPIO_DIO  = 0;
	GPIO_STB  = 0;
}

/*
    结束传输数据
*/
void TM1668_End(void)
{
	GPIO_CLK  = 1;
	GPIO_DIO  = 1;
	GPIO_STB  = 1;
	Delay_SEG(1);
}

#if		0
#define	SPI_DELAY()	Delay_SEG(1)
#else
#define	SPI_DELAY()
#endif



/*
    向1688写入一个数据。（写一个bit时需要在时钟的上升沿操作）
*/
void TM1668_WriteByte(unsigned char byte)
{
 data unsigned char i=8;
 
// EA=0;
 while(i--)
 {
	GPIO_CLK = 0;
	Delay_SEG(1);
	GPIO_DIO = (byte&0x01);
	Delay_SEG(1);
	GPIO_CLK = 1;
	byte>>=1;
 }
 
	
 
 
// for(i=0; i<8; i++)
// {
//	GPIO_CLK = 0;
//	Delay_SEG(1);
//	GPIO_DIO = (byte&0x01);
//	Delay_SEG(1);
//	GPIO_CLK = 1;
////	Delay_SEG(1);
//	byte>>=1;
// }
}


/*
	地址增加模式写入n个字节数据，从SRAM起始地址开始写
	p：写的数据首地址		nBytes：写入数据个数(<=14)		brightness：显示亮度
 */
void TM1668_WriteBytesAddrIncrease(unsigned char *p, unsigned char nBytes, unsigned char brightness)
{
	unsigned char i = 0;

	TM1668_Start();
	TM1668_WriteByte(GRID7_SEG10);				/* 设置显示模式：7位10段 */
	TM1668_End();

	TM1668_Start();
	TM1668_WriteByte(CMD_DataWriteIncrease);	/* 设置数据命令：地址自增 */
	TM1668_End();

	TM1668_Start();
	TM1668_WriteByte(ADD_00H);					/*  设置显示地址：起始地址 */
	for (i = 0; i < nBytes; i++)
	{
		TM1668_WriteByte(p[i]);
	}
	TM1668_End();

	TM1668_Start();
	TM1668_WriteByte(brightness);				/* 显示控制命令：亮度调节 */
	TM1668_End();
}

/*
	地址增加模式写入n个字节数据，
	p：写的数据		addr：地址		brightness：显示亮度
 */
void TM1668_WriteBytesAddr(unsigned char dat, unsigned char addr)
{
	TM1668_Start();
	TM1668_WriteByte(addr);					/* 设置显示地址：起始地址 */
	TM1668_WriteByte(dat);
	TM1668_End();
}

void set_brightness(unsigned char class){
	TM1668_Start();
	TM1668_WriteByte(class);				/* 显示控制命令：亮度调节 */
	TM1668_End();
}

void set_addr_mode(){
	TM1668_Start();
	TM1668_WriteByte(GRID7_SEG10);				/* 设置显示模式：7位10段 */
	TM1668_End();

	TM1668_Start();
	TM1668_WriteByte(CMD_DataWriteFixed);	/* 设置数据命令：地址固定 */
	TM1668_End();

} 
/*
	地址固定模式写入n个字节数据，从SRAM起始地址开始写
	p：写的数据首地址		nBytes：写入数据个数(<=14)		brightness：显示亮度
 */
void TM1668_WriteBytesAddrFixed(unsigned char *p, unsigned char nBytes, unsigned char brightness)
{
	unsigned char i = 0;

	TM1668_Start();
	TM1668_WriteByte(GRID7_SEG10);				/* 设置显示模式：7位10段 */
	TM1668_End();

	TM1668_Start();
	TM1668_WriteByte(CMD_DataWriteFixed);		/* 设置数据命令：地址固定 */
	TM1668_End();

	for (i = 0; i < nBytes; i++)
	{
		TM1668_Start();
		TM1668_WriteByte(ADD_00H + i);			/* 设置显示地址：起始地址 */
		TM1668_WriteByte(p[i]);
		TM1668_End();
	}

	TM1668_Start();
	TM1668_WriteByte(brightness);				/* 显示控制命令：亮度调节 */
	TM1668_End();
}

/*
    初始化，1668内部显示寄存器清零，防止出现乱码，并关闭显示
*/
void TM1668_Init(void)
{
	unsigned char i = 0;

	TM1668_Start();
	TM1668_WriteByte(GRID7_SEG10);				/* 设置显示模式：7位10段 */
	TM1668_End();

	TM1668_Start();
	TM1668_WriteByte(CMD_DataWriteIncrease);	/* 设置数据命令：地址自增 */
	TM1668_End();

	TM1668_Start();
	TM1668_WriteByte(ADD_00H);					/* 设置显示地址：起始地址 */
	for (i = 0; i < 14; i++)
	{
		TM1668_WriteByte(0);
	}
	TM1668_End();

	TM1668_Start();
	TM1668_WriteByte(DSP_OFF);				    /* 显示控制命令：亮度调节 */
	TM1668_End();
}

void dis_off(void){
	TM1668_Start();
	TM1668_WriteByte(DSP_OFF);				    /* 显示控制命令：亮度调节 */
	TM1668_End();
}